﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace Hsenl {
    public static class HTaskBodyPool {
        private static readonly ConcurrentDictionary<Type, ConcurrentQueue<IHTaskBodyBase>> _pool = new();

        internal static TBody RentBody<TBody>() where TBody : IHTaskBodyBase, new() {
            var type = typeof(TBody);
            if (!_pool.TryGetValue(type, out var queue)) {
                return new TBody();
            }

            if (!queue.TryDequeue(out var value)) {
                return new TBody();
            }

            var ret = (TBody)value;
            ret.Init();

            if (queue.Count == 0) {
                // _pool.Remove(type);
            }

            return ret;
        }

        internal static IHTaskBodyBase RentBody(Type type) {
            if (!_pool.TryGetValue(type, out var queue)) {
                return (IHTaskBody)Activator.CreateInstance(type)!;
            }

            if (!queue.TryDequeue(out var value)) {
                return (IHTaskBodyBase)Activator.CreateInstance(type)!;
            }

            return value;
        }

        internal static void ReturnBody(IHTaskBodyBase taskBody) {
            taskBody.Dispose();
            var type = taskBody.GetType();
            if (!_pool.TryGetValue(type, out var queue)) {
                queue = new();
                _pool[type] = queue;
            }

            queue.Enqueue(taskBody);
        }

        public static void Clear() {
            _pool.Clear();
        }
    }
}